Skip to content

feat(API): expose PDF heading-level inference in the service API - #3874

Open
DanielNg0729 wants to merge 1 commit into
docling-project:mainfrom
DanielNg0729:feat/serve-heading-hierarchy-options
Open

feat(API): expose PDF heading-level inference in the service API#3874
DanielNg0729 wants to merge 1 commit into
docling-project:mainfrom
DanielNg0729:feat/serve-heading-hierarchy-options

Conversation

@DanielNg0729

@DanielNg0729 DanielNg0729 commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Issue resolved by this Pull Request:
Part of docling-project/docling-serve#646

Hi maintainers, the PR #3633 and #3688 have added inference of section-header levels from PDF bookmarks, outline numbering and font style, configurable via PdfPipelineOptions.heading_hierarchy_options and off by default. Those options were not reachable from the service API, so every heading returned by docling-serve stayed at level=1 and the document hierarchy came back flat.

Since docling-project/docling-serve#575 moved the service request models into docling core, the API options model lives here while the pipeline mapping lives in docling-jobkit. Exposing this therefore takes three coordinated PRs:

  1. this PR i add the option to ConvertDocumentsOptions
  2. feat(API): expose PDF heading-level inference in the service API docling-jobkit#212 i map it onto PdfPipelineOptions and retain parsed pages for the style signal
  3. feat(API): expose PDF heading-level inference in the service API docling-serve#662 make changes in UI toggle and regenerated API docs

Important

Note that if this is going through, we must merge in the order from 1 -> 3.

This PR adds heading_hierarchy_options to ConvertDocumentsOptions, typed as the existing HeadingHierarchyOptions so the API mirrors PdfPipelineOptions.heading_hierarchy_options field-for-field rather than introducing a parallel flat schema. That keeps one place to learn and avoids drift as the pipeline options evolve, and it means the nested knobs (use_bookmarks, use_numbering, use_style, numbering_schemes, max_level, bookmark_match_threshold) come along for free, including their ge/le bounds and their descriptions in generated API docs.

The nested model also works over multipart/form-data, where docling-serve's FormDepends accepts nested models as JSON strings, verified in docling-project/docling-serve#662.

Verification

Schema generation, defaults and validation:

  • ConvertDocumentsOptions().heading_hierarchy_options.enabled is False
  • model_json_schema() resolves the $ref and serializes both examples
  • nested values parse ({"enabled": true, "max_level": 4}), unset keys keep their model defaults
  • out-of-range values are rejected (max_level: 0 raises)

End-to-end through docling-serve's /v1/convert/file, converting 2408.09869v5.pdf with all three PRs applied:

section-header levels
option omitted (default) {1: 20}
{"enabled": true} {1: 8, 2: 6, 3: 4, 4: 2}

3.1 PDF backends → level 2, Layout Analysis Model → level 3, Abstract → level 2. 12 of 20 headings corrected, and the default path is unchanged.

Checklist:

  • Documentation has been updated, if necessary.
  • Examples have been added, if necessary.
  • Tests have been added, if necessary.

Signed-off-by: Daniel Nguyen <danielnguyenh07@gmail.com>
@github-actions

Copy link
Copy Markdown
Contributor

DCO Check Passed

Thanks @DanielNg0729, all your commits are properly signed off. 🎉

@mergify

mergify Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🟢 Merge protection satisfied — ready to merge.

Show 1 satisfied protection

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?(!)?:

@DanielNg0729 DanielNg0729 changed the title feat(pdf): expose PDF heading-level inference in the service API feat(API): expose PDF heading-level inference in the service API Jul 25, 2026
@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant